package ibsp.common.nio.core.buffer;

import java.io.FilterOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.EnumSet;
import java.util.Set;

/**
 * A {@link IoBuffer} that wraps a buffer and proxies any operations to it.
 * <p>
 * You can think this class like a {@link FilterOutputStream}. All operations
 * are proxied by default so that you can extend this class and override
 * existing operations selectively. You can introduce new operations, too.
 * 
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev: 671827 $, $Date: 2008-06-26 10:49:48 +0200 (Thu, 26 Jun 2008)
 *          $
 */
public class IoBufferWrapper extends IoBuffer {

	/**
	 * The buffer proxied by this proxy.
	 */
	private final IoBuffer buf;

	/**
	 * Create a new instance.
	 * 
	 * @param buf
	 *            the buffer to be proxied
	 */
	protected IoBufferWrapper(IoBuffer buf) {
		if (buf == null) {
			throw new NullPointerException("buf");
		}
		this.buf = buf;
	}

	/**
	 * Returns the parent buffer that this buffer wrapped.
	 */
	public IoBuffer getParentBuffer() {
		return buf;
	}

	@Override
	public boolean isDirect() {
		return buf.isDirect();
	}

	@Override
	public ByteBuffer buf() {
		return buf.buf();
	}

	@Override
	public int capacity() {
		return buf.capacity();
	}

	@Override
	public int position() {
		return buf.position();
	}

	@Override
	public IoBuffer position(int newPosition) {
		buf.position(newPosition);
		return this;
	}

	@Override
	public int limit() {
		return buf.limit();
	}

	@Override
	public IoBuffer limit(int newLimit) {
		buf.limit(newLimit);
		return this;
	}

	@Override
	public IoBuffer mark() {
		buf.mark();
		return this;
	}

	@Override
	public IoBuffer reset() {
		buf.reset();
		return this;
	}

	@Override
	public IoBuffer clear() {
		buf.clear();
		return this;
	}

	@Override
	public IoBuffer sweep() {
		buf.sweep();
		return this;
	}

	@Override
	public IoBuffer sweep(byte value) {
		buf.sweep(value);
		return this;
	}

	@Override
	public IoBuffer flip() {
		buf.flip();
		return this;
	}

	@Override
	public IoBuffer rewind() {
		buf.rewind();
		return this;
	}

	@Override
	public int remaining() {
		return buf.remaining();
	}

	@Override
	public boolean hasRemaining() {
		return buf.hasRemaining();
	}

	@Override
	public byte get() {
		return buf.get();
	}

	@Override
	public short getUnsigned() {
		return buf.getUnsigned();
	}

	@Override
	public IoBuffer put(byte b) {
		buf.put(b);
		return this;
	}

	@Override
	public byte get(int index) {
		return buf.get(index);
	}

	@Override
	public short getUnsigned(int index) {
		return buf.getUnsigned(index);
	}

	@Override
	public IoBuffer put(int index, byte b) {
		buf.put(index, b);
		return this;
	}

	@Override
	public IoBuffer get(byte[] dst, int offset, int length) {
		buf.get(dst, offset, length);
		return this;
	}

	@Override
	public IoBuffer getSlice(int index, int length) {
		return buf.getSlice(index, length);
	}

	@Override
	public IoBuffer getSlice(int length) {
		return buf.getSlice(length);
	}

	@Override
	public IoBuffer get(byte[] dst) {
		buf.get(dst);
		return this;
	}

	@Override
	public IoBuffer put(IoBuffer src) {
		buf.put(src);
		return this;
	}

	@Override
	public IoBuffer put(ByteBuffer src) {
		buf.put(src);
		return this;
	}

	@Override
	public IoBuffer put(byte[] src, int offset, int length) {
		buf.put(src, offset, length);
		return this;
	}

	@Override
	public IoBuffer put(byte[] src) {
		buf.put(src);
		return this;
	}

	@Override
	public IoBuffer compact() {
		buf.compact();
		return this;
	}

	@Override
	public String toString() {
		return buf.toString();
	}

	@Override
	public int hashCode() {
		return buf.hashCode();
	}

	@Override
	public boolean equals(Object ob) {
		return buf.equals(ob);
	}

	public int compareTo(IoBuffer that) {
		return buf.compareTo(that);
	}

	@Override
	public ByteOrder order() {
		return buf.order();
	}

	@Override
	public IoBuffer order(ByteOrder bo) {
		buf.order(bo);
		return this;
	}

	@Override
	public char getChar() {
		return buf.getChar();
	}

	@Override
	public IoBuffer putChar(char value) {
		buf.putChar(value);
		return this;
	}

	@Override
	public char getChar(int index) {
		return buf.getChar(index);
	}

	@Override
	public IoBuffer putChar(int index, char value) {
		buf.putChar(index, value);
		return this;
	}

	@Override
	public CharBuffer asCharBuffer() {
		return buf.asCharBuffer();
	}

	@Override
	public short getShort() {
		return buf.getShort();
	}

	@Override
	public int getUnsignedShort() {
		return buf.getUnsignedShort();
	}

	@Override
	public IoBuffer putShort(short value) {
		buf.putShort(value);
		return this;
	}

	@Override
	public short getShort(int index) {
		return buf.getShort(index);
	}

	@Override
	public int getUnsignedShort(int index) {
		return buf.getUnsignedShort(index);
	}

	@Override
	public IoBuffer putShort(int index, short value) {
		buf.putShort(index, value);
		return this;
	}

	@Override
	public ShortBuffer asShortBuffer() {
		return buf.asShortBuffer();
	}

	@Override
	public int getInt() {
		return buf.getInt();
	}

	@Override
	public long getUnsignedInt() {
		return buf.getUnsignedInt();
	}

	@Override
	public IoBuffer putInt(int value) {
		buf.putInt(value);
		return this;
	}

	@Override
	public int getInt(int index) {
		return buf.getInt(index);
	}

	@Override
	public long getUnsignedInt(int index) {
		return buf.getUnsignedInt(index);
	}

	@Override
	public IoBuffer putInt(int index, int value) {
		buf.putInt(index, value);
		return this;
	}

	@Override
	public IntBuffer asIntBuffer() {
		return buf.asIntBuffer();
	}

	@Override
	public long getLong() {
		return buf.getLong();
	}

	@Override
	public IoBuffer putLong(long value) {
		buf.putLong(value);
		return this;
	}

	@Override
	public long getLong(int index) {
		return buf.getLong(index);
	}

	@Override
	public IoBuffer putLong(int index, long value) {
		buf.putLong(index, value);
		return this;
	}

	@Override
	public LongBuffer asLongBuffer() {
		return buf.asLongBuffer();
	}

	@Override
	public float getFloat() {
		return buf.getFloat();
	}

	@Override
	public IoBuffer putFloat(float value) {
		buf.putFloat(value);
		return this;
	}

	@Override
	public float getFloat(int index) {
		return buf.getFloat(index);
	}

	@Override
	public IoBuffer putFloat(int index, float value) {
		buf.putFloat(index, value);
		return this;
	}

	@Override
	public FloatBuffer asFloatBuffer() {
		return buf.asFloatBuffer();
	}

	@Override
	public double getDouble() {
		return buf.getDouble();
	}

	@Override
	public IoBuffer putDouble(double value) {
		buf.putDouble(value);
		return this;
	}

	@Override
	public double getDouble(int index) {
		return buf.getDouble(index);
	}

	@Override
	public IoBuffer putDouble(int index, double value) {
		buf.putDouble(index, value);
		return this;
	}

	@Override
	public DoubleBuffer asDoubleBuffer() {
		return buf.asDoubleBuffer();
	}

	@Override
	public String getHexDump() {
		return buf.getHexDump();
	}

	@Override
	public String getString(int fieldSize, CharsetDecoder decoder) throws CharacterCodingException {
		return buf.getString(fieldSize, decoder);
	}

	@Override
	public String getString(CharsetDecoder decoder) throws CharacterCodingException {
		return buf.getString(decoder);
	}

	@Override
	public String getPrefixedString(CharsetDecoder decoder) throws CharacterCodingException {
		return buf.getPrefixedString(decoder);
	}

	@Override
	public String getPrefixedString(int prefixLength, CharsetDecoder decoder) throws CharacterCodingException {
		return buf.getPrefixedString(prefixLength, decoder);
	}

	@Override
	public IoBuffer putString(CharSequence in, int fieldSize, CharsetEncoder encoder) throws CharacterCodingException {
		buf.putString(in, fieldSize, encoder);
		return this;
	}

	@Override
	public IoBuffer putString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException {
		buf.putString(in, encoder);
		return this;
	}

	@Override
	public IoBuffer putPrefixedString(CharSequence in, CharsetEncoder encoder) throws CharacterCodingException {
		buf.putPrefixedString(in, encoder);
		return this;
	}

	@Override
	public IoBuffer putPrefixedString(CharSequence in, int prefixLength, CharsetEncoder encoder) throws CharacterCodingException {
		buf.putPrefixedString(in, prefixLength, encoder);
		return this;
	}

	@Override
	public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, CharsetEncoder encoder)
			throws CharacterCodingException {
		buf.putPrefixedString(in, prefixLength, padding, encoder);
		return this;
	}

	@Override
	public IoBuffer putPrefixedString(CharSequence in, int prefixLength, int padding, byte padValue, CharsetEncoder encoder)
			throws CharacterCodingException {
		buf.putPrefixedString(in, prefixLength, padding, padValue, encoder);
		return this;
	}

	@Override
	public IoBuffer skip(int size) {
		buf.skip(size);
		return this;
	}

	@Override
	public IoBuffer fill(byte value, int size) {
		buf.fill(value, size);
		return this;
	}

	@Override
	public IoBuffer fillAndReset(byte value, int size) {
		buf.fillAndReset(value, size);
		return this;
	}

	@Override
	public IoBuffer fill(int size) {
		buf.fill(size);
		return this;
	}

	@Override
	public IoBuffer fillAndReset(int size) {
		buf.fillAndReset(size);
		return this;
	}

	@Override
	public boolean isAutoExpand() {
		return buf.isAutoExpand();
	}

	@Override
	public IoBuffer setAutoExpand(boolean autoExpand) {
		buf.setAutoExpand(autoExpand);
		return this;
	}

	@Override
	public IoBuffer expand(int pos, int expectedRemaining) {
		buf.expand(pos, expectedRemaining);
		return this;
	}

	@Override
	public IoBuffer expand(int expectedRemaining) {
		buf.expand(expectedRemaining);
		return this;
	}

	@Override
	public Object getObject() throws ClassNotFoundException {
		return buf.getObject();
	}

	@Override
	public Object getObject(ClassLoader classLoader) throws ClassNotFoundException {
		return buf.getObject(classLoader);
	}

	@Override
	public IoBuffer putObject(Object o) {
		buf.putObject(o);
		return this;
	}

	@Override
	public InputStream asInputStream() {
		return buf.asInputStream();
	}

	@Override
	public OutputStream asOutputStream() {
		return buf.asOutputStream();
	}

	@Override
	public IoBuffer duplicate() {
		return buf.duplicate();
	}

	@Override
	public IoBuffer slice() {
		return buf.slice();
	}

	@Override
	public IoBuffer asReadOnlyBuffer() {
		return buf.asReadOnlyBuffer();
	}

	@Override
	public byte[] array() {
		return buf.array();
	}

	@Override
	public int arrayOffset() {
		return buf.arrayOffset();
	}

	@Override
	public int minimumCapacity() {
		return buf.minimumCapacity();
	}

	@Override
	public IoBuffer minimumCapacity(int minimumCapacity) {
		buf.minimumCapacity(minimumCapacity);
		return this;
	}

	@Override
	public IoBuffer capacity(int newCapacity) {
		buf.capacity(newCapacity);
		return this;
	}

	@Override
	public boolean isReadOnly() {
		return buf.isReadOnly();
	}

	@Override
	public int markValue() {
		return buf.markValue();
	}

	@Override
	public boolean hasArray() {
		return buf.hasArray();
	}

	@Override
	public void free() {
		buf.free();
	}

	@Override
	public boolean isDerived() {
		return buf.isDerived();
	}

	@Override
	public boolean isAutoShrink() {
		return buf.isAutoShrink();
	}

	@Override
	public IoBuffer setAutoShrink(boolean autoShrink) {
		buf.setAutoShrink(autoShrink);
		return this;
	}

	@Override
	public IoBuffer shrink() {
		buf.shrink();
		return this;
	}

	@Override
	public int getMediumInt() {
		return buf.getMediumInt();
	}

	@Override
	public int getUnsignedMediumInt() {
		return buf.getUnsignedMediumInt();
	}

	@Override
	public int getMediumInt(int index) {
		return buf.getMediumInt(index);
	}

	@Override
	public int getUnsignedMediumInt(int index) {
		return buf.getUnsignedMediumInt(index);
	}

	@Override
	public IoBuffer putMediumInt(int value) {
		buf.putMediumInt(value);
		return this;
	}

	@Override
	public IoBuffer putMediumInt(int index, int value) {
		buf.putMediumInt(index, value);
		return this;
	}

	@Override
	public String getHexDump(int lengthLimit) {
		return buf.getHexDump(lengthLimit);
	}

	@Override
	public boolean prefixedDataAvailable(int prefixLength) {
		return buf.prefixedDataAvailable(prefixLength);
	}

	@Override
	public boolean prefixedDataAvailable(int prefixLength, int maxDataLength) {
		return buf.prefixedDataAvailable(prefixLength, maxDataLength);
	}

	@Override
	public int indexOf(byte b) {
		return buf.indexOf(b);
	}

	@Override
	public <E extends Enum<E>> E getEnum(Class<E> enumClass) {
		return buf.getEnum(enumClass);
	}

	@Override
	public <E extends Enum<E>> E getEnum(int index, Class<E> enumClass) {
		return buf.getEnum(index, enumClass);
	}

	@Override
	public <E extends Enum<E>> E getEnumShort(Class<E> enumClass) {
		return buf.getEnumShort(enumClass);
	}

	@Override
	public <E extends Enum<E>> E getEnumShort(int index, Class<E> enumClass) {
		return buf.getEnumShort(index, enumClass);
	}

	@Override
	public <E extends Enum<E>> E getEnumInt(Class<E> enumClass) {
		return buf.getEnumInt(enumClass);
	}

	@Override
	public <E extends Enum<E>> E getEnumInt(int index, Class<E> enumClass) {
		return buf.getEnumInt(index, enumClass);
	}

	@Override
	public IoBuffer putEnum(Enum<?> e) {
		buf.putEnum(e);
		return this;
	}

	@Override
	public IoBuffer putEnum(int index, Enum<?> e) {
		buf.putEnum(index, e);
		return this;
	}

	@Override
	public IoBuffer putEnumShort(Enum<?> e) {
		buf.putEnumShort(e);
		return this;
	}

	@Override
	public IoBuffer putEnumShort(int index, Enum<?> e) {
		buf.putEnumShort(index, e);
		return this;
	}

	@Override
	public IoBuffer putEnumInt(Enum<?> e) {
		buf.putEnumInt(e);
		return this;
	}

	@Override
	public IoBuffer putEnumInt(int index, Enum<?> e) {
		buf.putEnumInt(index, e);
		return this;
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSet(Class<E> enumClass) {
		return buf.getEnumSet(enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSet(int index, Class<E> enumClass) {
		return buf.getEnumSet(index, enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSetShort(Class<E> enumClass) {
		return buf.getEnumSetShort(enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSetShort(int index, Class<E> enumClass) {
		return buf.getEnumSetShort(index, enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSetInt(Class<E> enumClass) {
		return buf.getEnumSetInt(enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSetInt(int index, Class<E> enumClass) {
		return buf.getEnumSetInt(index, enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSetLong(Class<E> enumClass) {
		return buf.getEnumSetLong(enumClass);
	}

	@Override
	public <E extends Enum<E>> EnumSet<E> getEnumSetLong(int index, Class<E> enumClass) {
		return buf.getEnumSetLong(index, enumClass);
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSet(Set<E> set) {
		buf.putEnumSet(set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSet(int index, Set<E> set) {
		buf.putEnumSet(index, set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSetShort(Set<E> set) {
		buf.putEnumSetShort(set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSetShort(int index, Set<E> set) {
		buf.putEnumSetShort(index, set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSetInt(Set<E> set) {
		buf.putEnumSetInt(set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSetInt(int index, Set<E> set) {
		buf.putEnumSetInt(index, set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSetLong(Set<E> set) {
		buf.putEnumSetLong(set);
		return this;
	}

	@Override
	public <E extends Enum<E>> IoBuffer putEnumSetLong(int index, Set<E> set) {
		buf.putEnumSetLong(index, set);
		return this;
	}
}